package com.webull.information.center.carwler.common.util.news;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.databind.JsonNode;
import com.webull.framework.util.UtilJson;
import com.webull.information.center.carwler.common.model.NewsInformation;
import com.webull.information.center.carwler.common.util.HttpClientUtil;
import com.webull.information.center.carwler.common.util.jsoup.HttpJsoupClient;
import com.webull.information.center.carwler.common.util.jsoup.JsoupModel;
import com.webull.information.center.common.constants.UrlConstants;
import com.webull.information.client.model.News;

/**
 * 华尔街见闻
 * 
 * @author smj
 * @Date 2017年7月7日上午11:07:51
 * @version 1.0
 *
 */
@Component
public class WallStreetCnNewsUitl {

	private @Autowired HttpClientUtil httpClientUtil;
	private @Autowired HttpJsoupClient httpJsoupClient;
	protected final Logger logger = LogManager.getLogger(getClass());

	/**
	 * 获取新浪个股资讯首页对象并解析新闻条目列表
	 * 
	 * @param url
	 * @return
	 * @since 0.1.0
	 */
	public List<WallItem> parseTopNewsList() {
		String json = httpClientUtil.getStringEntity(UrlConstants.wallStreetBannerJsonUrl, false);
		JsonNode jsonNode = UtilJson.readValue(json, JsonNode.class);
		List<WallItem> itmes = parseNewsList0(jsonNode, News.HomeType.frontPage, Pix.wall);
		return itmes;
	}


	public List<WallItem> parseHomeNewsList() {
		String json = httpClientUtil.getStringEntity(UrlConstants.wallStreetHomeJsonUrl, false);
		JsonNode jsonNode = UtilJson.readValue(json, JsonNode.class);
		List<WallItem> itmes = parseNewsList0(jsonNode, News.HomeType.top, Pix.wall);
		return itmes;
	}


	public List<WallItem> parseGoldTopNewsList() {
		String json = httpClientUtil.getStringEntity(UrlConstants.goldBannerJsonUrl, false);
		JsonNode jsonNode = UtilJson.readValue(json, JsonNode.class);
		List<WallItem> itmes = parseNewsList1(jsonNode, News.HomeType.frontPage, Pix.gold);
		return itmes;
	}

	public List<WallItem> parseGlodHomeNewsList() {
		String json = httpClientUtil.getStringEntity(UrlConstants.goldHomeJsonUrl, false);
		JsonNode jsonNode = UtilJson.readValue(json, JsonNode.class);
		List<WallItem> itmes = parseNewsList0(jsonNode, News.HomeType.top, Pix.gold);
		return itmes;
	}

	private static String convertContext(String context, JsonNode arg0, boolean isWallCn) {

		if (StringUtils.isBlank(context))
			return null;
		// 参数替换
		if (arg0 != null && arg0.isArray())
			for (JsonNode v0 : arg0) {
				String type = v0.at("/type").asText();
				String placeholder = v0.at("/placeholder").asText();
				String elemtHtml = null;
				if ("image".equalsIgnoreCase(type)) {
					String src = v0.at("/src").asText();
					if (StringUtils.isNotBlank(src))
						elemtHtml = "<img src='" + src + "'>";
				} else if ("audio".equalsIgnoreCase(type)) {
					String uri = v0.at("/uri").asText();
					String title = v0.at("/title").asText();
					String style = " font-size: 15px; margin-bottom: 2px;";
					elemtHtml = "<div><div style='" + style + "'> 标题:" + title
							+ "</div><audio src=" + uri
							+ " controls autoplay></audio></div>";
				}
				if (StringUtils.isNotBlank(placeholder) && StringUtils.isNotBlank(elemtHtml))
					context = StringUtils.replace(context, placeholder, elemtHtml);
			}

		context = isWallCn ? parseJsoup(context) : parseJsoup2(context);


		String ss = "\\s*";
		// 、电商和新零售。</p><p>小米曾被质疑商 //换行
		String huanhang = StringUtils.replace("(?i)>{s}<{s}p{s}>", "{s}", ss);
		context = StringUtils.replacePattern(context, huanhang, "><div style='height:19px;'></div><p>");

		return context;
	}


	private static String parseJsoup(String context) {
		context = StringEscapeUtils.unescapeHtml4(context);

		Document doc = Jsoup.parse(context);

		/*
		 * 第一个 <p> 含有em，则这个 <p> 要删除掉，代表斜体注解信息
		 */
		Optional.ofNullable(doc.getElementsByTag("p").first())//
				.filter(p0 -> !p0.getElementsByTag("em").isEmpty()//
						|| (p0.text() + "").matches("\\s*本文来自.*?更多资讯.*"))//
				.ifPresent(p0 -> p0.remove());

		/*
		 * 尾部的ad广告位
		 */
		Optional.ofNullable(doc.getElementsByTag("p").last())//
				.filter(p0 -> p0.getElementsByTag("img").size() == 1 && p0.childNodes().size() <= 1)//
				.ifPresent(p0 -> p0.remove());

		if (Optional.ofNullable(doc.getElementsByTag("p").last())//
				.filter(p0 -> (p0.text() + "").matches(".{0,8}更新中.{0,8}"))//
				.isPresent()) {
			return "";
		}
		final String regex0 = "^\\s*本文[来|作].*?华尔街见闻.*?";

		Optional.ofNullable(doc.select("div")).filter(pa -> pa.size() >= 1).ifPresent(pa -> {
			for (Element d0 : pa) {
				if ((d0.text() + "").matches(regex0))
					d0.remove();
			}
		});
		Optional.ofNullable(doc.getElementsByTag("p"))//
				.filter(ps -> ps.size() > 0)//
				.ifPresent(ps -> {

					for0: for (Element p0 : ps) {
						// <p>作者丨全天候科技 徐志成<br>编辑丨全天候科技 张彬彬</p>
						String text0 = p0.text() + "";

						if (text0.matches(".{0,3}作者.{0,3}\\|.{1,15}")) {
							p0.remove();
							continue for0;
						}
						//
						else if (text0.matches(".{0,3}播音.{0,3}\\|.{1,15}")) {
							p0.remove();
							continue for0;
						} else if (text0.matches(".{0,3}作者.{0,3}\\|.*?编辑.{0,3}\\|.*?")) {
							p0.remove();
							continue for0;
						} // <p><strong>本文来源于微信公众号“云锋金融”，原标题为“下一代零售”，授权华尔街见闻发布。</strong></p>
							// 下载APP
						else if (text0.matches(regex0)) {
							p0.remove();
							continue for0;
						}

						// www.ig.com 一键下单 content.etoro.com
						Optional.ofNullable(p0.select("p>a")).filter(pa -> pa.size() >= 1)
								.ifPresent(pa->  {
									for (Element a0: pa) {
										if (a0.absUrl("href")
												.matches("(?i).*(content\\.etoro\\.com|www\\.ig\\.com){1}.*"))
										a0.remove();
									}
								});
					}
				}
		);
		doc.getElementsByTag("img").forEach(v -> v.removeAttr("style"));
		return doc.body().html();
	}

	/**
	 * 黄金头条内容解析
	 * 
	 * @param context
	 * @return
	 */
	private static String parseJsoup2(String context) {
		context = StringEscapeUtils.unescapeHtml4(context);

		Document doc = Jsoup.parse(context);

		/*
		 * 第一个 <p> 含有em，则这个 <p> 要删除掉，代表斜体注解信息
		 */
		Optional.ofNullable(doc.getElementsByTag("p").first())//
				.filter(p0 -> !p0.getElementsByTag("em").isEmpty()//
						|| (p0.text() + "").matches("\\s*本文来自.*?更多资讯.*"))//
				.ifPresent(p0 -> p0.remove());

		/*
		 * 尾部的ad广告位
		 */
		Optional.ofNullable(doc.getElementsByTag("p").last())//
				.filter(p0 -> p0.getElementsByTag("img").size() == 1 && p0.childNodes().size() <= 1)//
				.ifPresent(p0 -> p0.remove());

		if (Optional.ofNullable(doc.getElementsByTag("p").last())//
				.filter(p0 -> (p0.text() + "").matches(".{0,8}黄金头条AI{0,8}"))//
				.isPresent()) {
			return "";
		}

		Optional.ofNullable(doc.getElementsByTag("p"))//
				.filter(ps -> ps.size() > 0)//
				.ifPresent(ps -> {
					for0: for (Element p0 : ps) {
						// <p>作者丨全天候科技 徐志成<br>编辑丨全天候科技 张彬彬</p>
						String text0 = p0.text() + "";
						// String text1 = p0.html() + "";
						// System.out.println(text0);
						if (text0.matches(".{0,3}本文作者.*")) {
							p0.remove();
							continue for0;
						}
						// 欢迎加微信
						else if (text0.matches(".*欢迎.{0,3}微信.*")) {
							p0.remove();
							continue for0;
						}
						// 欢迎加微信
						else if (text0.matches(".*?本文[来|作].*?华尔街见闻.*?")) {
							p0.remove();
							continue for0;
						}



						// www.ig.com 一键下单 content.etoro.com
						Optional.ofNullable(p0.select("p>a")).filter(pa -> pa.size() >= 1).ifPresent(pa -> {
							for (Element a0 : pa) {
								if (a0.absUrl("href").matches("(?i).*(content\\.etoro\\.com|www\\.ig\\.com){1}.*"))
									a0.remove();
							}
						});
					}
				});
		doc.getElementsByTag("img").forEach(v -> v.removeAttr("style"));
		return doc.body().html();
	}

	public static void main(String[] args) throws IOException {

		String context = FileUtils.readFileToString(new File("C:\\Users\\smj\\Desktop\\编辑1.txt"), "utf-8");
		// String context2 = FileUtils.readFileToString(new
		// File("C:\\Users\\smj\\Desktop\\编辑2.txt"), "utf-8");

		System.out.println(parseJsoup2(context));
	}

	private static String convertSource(String source) {
		if (StringUtils.contains(source, " "))
			source = StringUtils.substringBefore(source, " ");
		return source;
	}


	/**
	 * 添加文本，并返回关联item
	 * 
	 * @param info0
	 */
	public List<WallItem> addTextReturnAssoc(NewsInformation info0, boolean needAssoc) {
		String id = info0.getNote(wallId);

		String url = StringUtils.replaceOnce(UrlConstants.wallStreetContextJsonUrl, "{id}", id);

		boolean isWallCn = StringUtils.startsWithIgnoreCase(info0.getUrl(), Pix.wall.getUrlPix());
		JsoupModel model = isWallCn ? JsoupModel.Mobile0
				: JsoupModel.Mobile1;

		Document document = httpJsoupClient.parseDocumentFromUrl(url, model);
		if (document == null)
			return null;
		JsonNode jsonNode = UtilJson.readValue(document.body().text(), JsonNode.class);
		if (!"20000".equals(jsonNode.at("/code").asText())) {
			return null;
		}

		// sdfkhsdkfhsdkf

		JsonNode arg0 = jsonNode.at("/data/content_args");

		info0.setContent(convertContext(jsonNode.at("/data/content").asText(null), arg0, isWallCn));

		if (!isWallCn || !needAssoc || StringUtils.isBlank(info0.getContent()))
			return null;


		return Optional.ofNullable(jsonNode.at("/data/related_articles"))//
				.filter(v -> v.isArray() && v.size() > 0)
				.map(vs -> {
					List<WallItem> itmes = new ArrayList<>();
					for (JsonNode v1 : vs) {
						WallItem item = genWallItem(v1, Pix.wall);
						if (item.check())
							itmes.add(item);
					}
					return itmes;
				}).orElse(null);

	}

	private WallItem genWallItem(JsonNode v1, Pix pix) {
		WallItem item = new WallItem();
		if (v1.at("/is_priced").asBoolean(false))
			return item;

		item.setHomeType(News.HomeType.top);
		item.setTitle(v1.at("/title").asText(null));
		item.setSummary(v1.at("/content_short").asText(null));

		item.setSourceName(Optional.ofNullable(StringUtils.stripToNull(v1.at("/source_name").asText(null)))
						.orElse(pix.getSourcePix()));

		String id_ = "" + v1.at("/id").asInt();
		item.setUrl(pix.getUrlPix() + id_);
		item.setWallId(id_);

		item.setImg(v1.at("/image_uri").asText(null));
		try {
			item.setNewsTime(new Date(Long.valueOf((v1.at("/display_time").asText(null) + "000"))));
		} catch (Exception e) {
		}
		return item;
	};

	private static final String urlPix = "m2.wallstreetcn.com/articles/";
	private static final String source0 = "华尔街见闻";

	private static final String urlPixg = "m-prod.goldtoutiao.com/articles/";
	private static final String sourceg = "黄金头条";

	private static enum Pix {
		wall, gold;
		private String getUrlPix() {
			if (this.equals(wall))
				return urlPix;
			if (this.equals(gold))
				return urlPixg;
			return "";
		}

		private String getSourcePix() {
			if (this.equals(wall))
				return source0;
			if (this.equals(gold))
				return sourceg;
			return "";
		}
	}

	private List<WallItem> parseNewsList0(JsonNode jsonNode, Integer homeType, Pix pix) {

		List<WallItem> itmes = new ArrayList<>();
		// A股新闻页面
		if (!"20000".equals(jsonNode.at("/code").asText()))
			return itmes;
		Optional.ofNullable(jsonNode.at("/data/items")).ifPresent(v -> {

			for0: for (JsonNode v1 : v) {
				if (!"article".equalsIgnoreCase(v1.at("/resource_type").asText())) // 非文章
					continue for0;

				if (v1.at("/resource/is_priced").asBoolean(false)) // 付费内容
					continue for0;

				String source = StringUtils.stripToNull(v1.at("/resource/source_name").asText(null));

				if (Pix.wall.equals(pix)) { // 华尔街跳过黄金头条内容
					String source2 = v1.at("/resource/author/display_name").asText(null);
					if (StringUtils.equalsIgnoreCase(source2, "黄金头条") || StringUtils.equalsIgnoreCase(source, "黄金头条"))
						continue for0;
				}

				WallItem item = new WallItem();
				String id_ = "" + v1.at("/resource/id").asInt();
				item.setUrl(pix.getUrlPix() + id_);
				item.setWallId(id_);
				item.setTitle(v1.at("/resource/title").asText(null));
				item.setSummary(v1.at("/resource/content_short").asText(null));
				// item.setUrl(v1.at("/resource/uri").asText(null));
				item.setImg(v1.at("/resource/image_uri").asText(null));
				item.setSourceName(	Optional.ofNullable(source)	.orElse(pix.getSourcePix()));
				item.setHomeType(homeType);
				try {
				item.setNewsTime(new Date(Long.valueOf((v1.at("/resource/display_time").asText(null) + "000"))));
				} catch (Exception e) {
				}
				
				if (item.check())
					itmes.add(item);

			}
		});

		return itmes;
	}

	private List<WallItem> parseNewsList1(JsonNode jsonNode, Integer homeType, Pix pix) {

		List<WallItem> itmes = new ArrayList<>();
		// A股新闻页面
		if (!"20000".equals(jsonNode.at("/code").asText()))
			return itmes;
		Optional.ofNullable(jsonNode.at("/data/items")).ifPresent(v -> {

			for (JsonNode v1 : v) {
				WallItem item = genWallItem(v1, pix);
				item.setHomeType(homeType);


				if (item.check())
					itmes.add(item);

			}
		});

		return itmes;
	}




	public static class WallItem {
		private Date newsTime;
		private String title;
		private String url;
		private String img;
		private String summary;
		private String sourceName;
		private Integer homeType;
		private String wallId;

		/**
		 * 出厂标准
		 * 
		 * @return
		 */
		private boolean check() {
			return StringUtils.isNotBlank(title)//
					&& StringUtils.isNotBlank(url)//
					// && StringUtils.isNotBlank(img)//
					&& newsTime != null //
					&& homeType != null;
		}
		public String getSourceName() {
			return convertSource(sourceName);
		}

		public void setSourceName(String sourceName) {
			this.sourceName = sourceName;
		}

		public Date getNewsTime() {
			return newsTime;
		}

		public void setNewsTime(Date newsTime) {
			this.newsTime = newsTime;
		}




		public String getImg() {
			return img;
		}

		public void setImg(String img) {
			this.img = img;
		}

		public String getSummary() {
			return summary;
		}


		public void setSummary(String summary) {
			this.summary = summary;
		}

		public String getTitle() {
			return title;
		}

		public void setTitle(String title) {
			this.title = title;
		}

		public String getUrl() {
			return url;
		}

		public void setUrl(String url) {
			this.url = url;
		}

		public Integer getHomeType() {
			return homeType;
		}

		public void setHomeType(Integer homeType) {
			this.homeType = homeType;
		}

		public String getWallId() {
			return wallId;
		}

		public void setWallId(String wallId) {
			this.wallId = wallId;
		}



	}

	public static final String wallId = "wallId";
}
